1 //-------------------------------------------------------------------------------------------------
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 // A simple template that implements a dynamically sized
6 // array using memory from the heap.
8 //-------------------------------------------------------------------------------------------------
18 // Make sure we're zeroed.
21 memset(this, 0, sizeof(*this));
24 // Makes sure that this goes away.
30 // Set the initial size of the array.
31 void SizeArray(_In_
unsigned long ulSlots
)
35 m_array
= VBAllocator::AllocateArray
<TYPE
>(ulSlots
);
40 // Copy the contents of one array into another.
41 void TransferFromArgument(DynamicArray
<TYPE
> *pda
)
45 m_cSlots
= pda
->m_cSlots
;
46 m_cEntries
= pda
->m_cEntries
;
47 m_array
= pda
->m_array
;
54 // Destroys the array.
58 for (unsigned i
= 0; i
< m_cEntries
; i
++)
60 // This will cause the contents of our thinggy to get
61 // destroyed. Neato, eh?
63 // Note ([....]): The destructor will not get called if the object you are storing
64 // in the array is a pointer, so you will have to remove every element yourself
65 // and call delete on it.
80 memset(this, 0, sizeof(DynamicArray
<TYPE
>));
83 // Resets the array without destroying any of its elements
84 // (good to use if the elements stored in the array are pointers).
94 memset(this, 0, sizeof(DynamicArray
<TYPE
>));
97 // Resets the array so it has no size.
104 // Manipulation methods.
107 // Get the number of entries in the array.
119 // Get an element of an array.
120 TYPE
&Element(unsigned iElement
)
122 VSASSERT(iElement
< m_cEntries
, "Out of range.");
124 return m_array
[iElement
];
127 // Grow the size of the array. Returns the first element that
130 TYPE
&Grow(ULONG cGrow
= 1)
132 VSASSERT(cGrow
> 0, "Must be greater than 0");
134 if (m_cEntries
+ cGrow
> m_cSlots
)
138 ULONG cExpand
= m_cSlots
> cGrow
? m_cSlots
: cGrow
;
140 TYPE
*rgt
= (TYPE
*)VBRealloc(
143 VBMath::Add(m_cSlots
, cExpand
),
146 // Zero the expanded array.
147 memset(rgt
+ m_cSlots
, 0, cExpand
* sizeof(TYPE
));
149 // Set the new memory.
154 // Get the element that was added.
155 unsigned cFirst
= m_cEntries
;
157 // Grow the number of slots used.
160 // Return the first element that was added.
161 return m_array
[cFirst
];
164 // Add an element to the end of the array.
166 void AddElement( const TYPE
& ElementToAdd
)
168 TYPE
& NewElement
= Grow();
169 NewElement
= ElementToAdd
;
173 void Shrink(ULONG cShrink
= 1)
175 VSASSERT(m_cEntries
>= cShrink
, "Underflow.");
177 for (unsigned i
= m_cEntries
; i
> m_cEntries
- cShrink
; )
182 // This will cause the contents of our thinggy to get
183 // destroyed. Neato, eh?
193 memset(m_array
+ m_cEntries
- cShrink
, 0, sizeof(TYPE
) * cShrink
);
194 m_cEntries
-= cShrink
;
197 // Add an element to the array.
198 TYPE
&Add(ULONG cAdd
= 1)
203 // Add element to the array and invoke the constructor properly.
204 TYPE
&CreateNew(ULONG cAdd
= 1)
206 TYPE
&rFirst
= Grow(cAdd
);
207 for (ULONG i
= 0; i
< cAdd
; ++i
)
209 new((void*)(&rFirst
+ i
)) TYPE();
214 // Remove an element from the array, even from the middle.
215 void Remove(ULONG iRemove
)
217 VSASSERT(iRemove
< m_cEntries
, "Index out of range.");
219 // Destroy the element.
221 m_array
[iRemove
].~TYPE();
224 // Copy the entries that appear after this one.
225 memmove(m_array
+ iRemove
,
226 m_array
+ iRemove
+ 1,
227 (m_cEntries
- iRemove
- 1) * sizeof(TYPE
));
229 // Manually remove the last element.
232 memset(m_array
+ m_cEntries
, 0, sizeof(TYPE
));
235 //. Insert an element into the array, even into the middle.
236 TYPE
&Insert(ULONG index
)
238 VSASSERT(index
<= m_cEntries
, "Index out of range.");
239 Grow(); // grow by 1 slot.
241 // Move all the entries that appear after this one back one slot.
242 // If some regions of the source area and the destination overlap, memmove ensures that the original source bytes in the overlapping region are copied before being overwritten.
243 memmove(m_array
+ index
+ 1,
245 (m_cEntries
- index
- 1) * sizeof(TYPE
));
248 memset(m_array
+ index
, 0, sizeof(TYPE
));
250 // Return the element.
251 return m_array
[index
];
254 // Copies the array element in fromIndex over the array element in toIndex and then
255 // removes the element at fromIndex.
256 void CopyOver(ULONG toIndex
, ULONG fromIndex
)
258 VSASSERT(toIndex
<= m_cEntries
&& fromIndex
<= m_cEntries
, "Index out of range.");
260 // Nothing to do if we are copying from and to the same index.
261 if (toIndex
== fromIndex
)
266 memcpy(m_array
+ toIndex
, m_array
+ fromIndex
, sizeof(TYPE
));
270 // Return the last slot in the array.
273 return m_array
[m_cEntries
- 1];